
package dk.unet.android.data.sql;

import dk.unet.android.data.queries.DeleteQuery;
import dk.unet.android.data.queries.InsertQuery;
import dk.unet.android.data.queries.Query;
import dk.unet.android.data.queries.SelectQuery;
import dk.unet.android.data.queries.UpdateQuery;
import java.util.Iterator;
import java.util.List;

/**
 *
 * @author Nicolai Willems
 */
public class SQLQueryCompiler {
    public static String compile(Query query){
        String result = "";
        if(query instanceof InsertQuery){ //Create
            result = compileInsertQuery((InsertQuery)query);
        }else if(query instanceof SelectQuery){ //Read
            result = compileSelectQuery((SelectQuery)query);
        }else if(query instanceof UpdateQuery){ //Update
            result = compileUpdateQuery((UpdateQuery)query);
        }else if(query instanceof DeleteQuery){ //Delete
            result = compileDeleteQuery((DeleteQuery)query);
        }else{
            //Do something about a non supported query
        }

        return result;
    }

    private static String compileInsertQuery(InsertQuery query){
        //Parameters first = table-name, second = fields, third = values
        final String queryString = "INSERT INTO %1$s(%2$s) VALUES(%3$s)";
        String[] fields = query.getFields();
        String[] values = query.getValues();
        String fieldList = "", valueList = "";

        if(fields.length > values.length)
            throw new UnsupportedOperationException("More fields than values specified");

        for (int i = 0; i < fields.length; i++) {
            String field = fields[i];
            String value = values[i];

            fieldList += ", "+field;
            valueList += ", "+value;
        }

        fieldList = fieldList.substring(2); //Magic constant equal to ", "
        valueList = valueList.substring(2);
        
        return String.format(queryString, query.getTable(), fieldList, valueList);
    }

    private static String compileSelectQuery(SelectQuery query){
        //Parameters first = fields, second = table-name, third = where clause
        final String queryString = "SELECT %1$s FROM %2$s WHERE %3$s";
        //Compile field list
        String fieldList = "";
        String[] fields = query.getFields();
        for (int i = 0; i < fields.length; i++) {
            String field = fields[i];
            fieldList += ", "+field;
        }
        fieldList = fieldList.substring(2); //Magic const = ", "

        //Compile where clause
        String whereClause = "";
        List<String> wheres = query.getWhere();
        for (Iterator<String> it = wheres.iterator(); it.hasNext();) {
            String where = it.next();
            whereClause += "AND "+where;
        }
        whereClause = whereClause.substring(4); //Magic const = "AND "

        //Compile query string
        return String.format(queryString, fields, query.getTable(), whereClause);
    }

    private static String compileUpdateQuery(UpdateQuery query) {
        //Parameters first = table-name, second = "field=value"-pairs, third = where clause
        final String queryString = "UPDATE %1$s SET %2$s WHERE %3$s";

        //Compile field=value-pairs
        String[] fields = query.getFields();
        String[] values = query.getValues();
        String fieldValuePairs = "";

        if(fields.length > values.length)
            throw new UnsupportedOperationException("More fields than values specified");

        for (int i = 0; i < fields.length; i++) {
            String field = fields[i];
            String value = values[i];

            fieldValuePairs += ", "+field+"="+value;
        }
        fieldValuePairs = fieldValuePairs.substring(2); //Magic const = ", "

        //Compile where clause
        String whereClause = "";
        List<String> wheres = query.getWhere();
        for (Iterator<String> it = wheres.iterator(); it.hasNext();) {
            String where = it.next();
            whereClause += "AND "+where;
        }
        whereClause = whereClause.substring(4); //Magic const = "AND "

        return String.format(queryString, query.getTable(), fieldValuePairs, whereClause);
    }

    private static String compileDeleteQuery(DeleteQuery query) {
        //Parameters first = table-name, second = where-clause
        final String queryString = "DELETE FROM %1$s WHERE %2$s";

        //Compile where clause
        String whereClause = "";
        List<String> wheres = query.getWhere();
        for (Iterator<String> it = wheres.iterator(); it.hasNext();) {
            String where = it.next();
            whereClause += "AND "+where;
        }
        whereClause = whereClause.substring(4); //Magic const = "AND "

        return String.format(queryString, query.getTable(), whereClause);
    }
}
